package top.bigdata.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.bigdata.mapper.ResultMapper;
import top.bigdata.model.entity.Result;
import top.bigdata.service.api.ResultService;

import java.sql.Timestamp;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

@Service
@RequiredArgsConstructor
@Slf4j
public class ResultServiceImpl implements ResultService {
    private final ResultMapper resultMapper;
    private final ObjectMapper objectMapper;

    @Override
    public <T> T cachedQuery(String id, Supplier<T> analyzer, Class<T> clazz) {
        var result = resultMapper.getResult(id);
        if (result != null) {
            // 缓存存在直接返回
            try {
                var data = objectMapper.readValue(result.getData(), clazz);
                // 更新缓存访问时间
                resultMapper.updateQueryTime(id, new Timestamp(System.currentTimeMillis()));
                return data;
            } catch (JsonProcessingException e) {
                log.error("json解析错误", e);
                return analyzer.get();
            }
        } else {
            // 缓存不存在，则调用分析器
            var data = analyzer.get();

            // 放入缓存
            try {
                resultMapper.addResult(new Result(id, new Timestamp(System.currentTimeMillis()), objectMapper.writeValueAsString(data)));
            } catch (JsonProcessingException e) {
                log.error("json解析错误", e);
                return null;
            }
            return data;
        }
    }

    @Override
    public <T> List<T> cachedQueryList(String id, Supplier<List<T>> analyzer, Consumer<List<T>> resultHandler, Class<T> elementClass) {
        var result = resultMapper.getResult(id);
        if (result != null) {
            // 缓存存在直接返回
            try {
                CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, elementClass);
                var data = objectMapper.readValue(result.getData(), listType);
                // 更新缓存访问时间
                resultMapper.updateQueryTime(id, new Timestamp(System.currentTimeMillis()));
                return (List<T>) data;
            } catch (JsonProcessingException e) {
                log.error("json解析错误", e);
                return analyzer.get();
            }
        } else {
            // 缓存不存在，则调用分析器
            var data = analyzer.get();
            // 处理分析结果
            if (resultHandler != null)
                resultHandler.accept(data);

            // 放入缓存
            try {
                resultMapper.addResult(new Result(id, new Timestamp(System.currentTimeMillis()), objectMapper.writeValueAsString(data)));
            } catch (JsonProcessingException e) {
                log.error("json解析错误", e);
                return null;
            }
            return data;
        }
    }

    @Override
    public <T> List<T> cachedQueryList(String id, Supplier<List<T>> analyzer, Class<T> elementClass) {
        return cachedQueryList(id, analyzer, null, elementClass);
    }
}
